/**
 * 浏览器工作流 - 通用工具函数
 * 提供各种实用工具函数
 */

/**
 * 工具函数命名空间
 */
const BrowserWorkUtils = {
  
  /**
   * 延迟执行函数
   * @param {number} ms - 延迟时间（毫秒）
   * @returns {Promise} Promise对象
   */
  delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  },

  /**
   * 防抖函数
   * @param {Function} func - 要防抖的函数
   * @param {number} wait - 等待时间
   * @param {boolean} immediate - 是否立即执行
   * @returns {Function} 防抖后的函数
   */
  debounce(func, wait, immediate) {
    let timeout;
    return function executedFunction(...args) {
      const later = () => {
        timeout = null;
        if (!immediate) func.apply(this, args);
      };
      const callNow = immediate && !timeout;
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
      if (callNow) func.apply(this, args);
    };
  },

  /**
   * 节流函数
   * @param {Function} func - 要节流的函数
   * @param {number} limit - 限制时间
   * @returns {Function} 节流后的函数
   */
  throttle(func, limit) {
    let inThrottle;
    return function(...args) {
      if (!inThrottle) {
        func.apply(this, args);
        inThrottle = true;
        setTimeout(() => inThrottle = false, limit);
      }
    };
  },

  /**
   * 生成唯一ID
   * @returns {string} 唯一标识符
   */
  generateId() {
    return 'bw_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now();
  },

  /**
   * 格式化日期
   * @param {Date|string} date - 日期对象或字符串
   * @param {string} format - 格式字符串
   * @returns {string} 格式化后的日期字符串
   */
  formatDate(date, format = 'YYYY-MM-DD HH:mm:ss') {
    const d = new Date(date);
    const year = d.getFullYear();
    const month = String(d.getMonth() + 1).padStart(2, '0');
    const day = String(d.getDate()).padStart(2, '0');
    const hours = String(d.getHours()).padStart(2, '0');
    const minutes = String(d.getMinutes()).padStart(2, '0');
    const seconds = String(d.getSeconds()).padStart(2, '0');

    return format
      .replace('YYYY', year)
      .replace('MM', month)
      .replace('DD', day)
      .replace('HH', hours)
      .replace('mm', minutes)
      .replace('ss', seconds);
  },

  /**
   * 深度克隆对象
   * @param {any} obj - 要克隆的对象
   * @returns {any} 克隆后的对象
   */
  deepClone(obj) {
    if (obj === null || typeof obj !== 'object') return obj;
    if (obj instanceof Date) return new Date(obj.getTime());
    if (obj instanceof Array) return obj.map(item => this.deepClone(item));
    if (typeof obj === 'object') {
      const cloned = {};
      Object.keys(obj).forEach(key => {
        cloned[key] = this.deepClone(obj[key]);
      });
      return cloned;
    }
  },

  /**
   * 存储管理器
   */
  storage: {
    /**
     * 获取存储数据
     * @param {string|Array} keys - 键名或键名数组
     * @returns {Promise} Promise对象
     */
    get(keys) {
      return new Promise((resolve, reject) => {
        if (typeof chrome !== 'undefined' && chrome.storage) {
          chrome.storage.sync.get(keys, (result) => {
            if (chrome.runtime.lastError) {
              reject(chrome.runtime.lastError);
            } else {
              resolve(result);
            }
          });
        } else {
          // 降级到localStorage
          try {
            const result = {};
            const keyArray = Array.isArray(keys) ? keys : [keys];
            keyArray.forEach(key => {
              const value = localStorage.getItem(`browserWork_${key}`);
              if (value !== null) {
                result[key] = JSON.parse(value);
              }
            });
            resolve(result);
          } catch (error) {
            reject(error);
          }
        }
      });
    },

    /**
     * 设置存储数据
     * @param {Object} items - 要存储的数据对象
     * @returns {Promise} Promise对象
     */
    set(items) {
      return new Promise((resolve, reject) => {
        if (typeof chrome !== 'undefined' && chrome.storage) {
          chrome.storage.sync.set(items, () => {
            if (chrome.runtime.lastError) {
              reject(chrome.runtime.lastError);
            } else {
              resolve();
            }
          });
        } else {
          // 降级到localStorage
          try {
            Object.keys(items).forEach(key => {
              localStorage.setItem(`browserWork_${key}`, JSON.stringify(items[key]));
            });
            resolve();
          } catch (error) {
            reject(error);
          }
        }
      });
    },

    /**
     * 删除存储数据
     * @param {string|Array} keys - 要删除的键名
     * @returns {Promise} Promise对象
     */
    remove(keys) {
      return new Promise((resolve, reject) => {
        if (typeof chrome !== 'undefined' && chrome.storage) {
          chrome.storage.sync.remove(keys, () => {
            if (chrome.runtime.lastError) {
              reject(chrome.runtime.lastError);
            } else {
              resolve();
            }
          });
        } else {
          // 降级到localStorage
          try {
            const keyArray = Array.isArray(keys) ? keys : [keys];
            keyArray.forEach(key => {
              localStorage.removeItem(`browserWork_${key}`);
            });
            resolve();
          } catch (error) {
            reject(error);
          }
        }
      });
    }
  },

  /**
   * DOM工具函数
   */
  dom: {
    /**
     * 等待元素出现
     * @param {string} selector - CSS选择器
     * @param {number} timeout - 超时时间（毫秒）
     * @returns {Promise<Element>} Promise对象
     */
    waitForElement(selector, timeout = 5000) {
      return new Promise((resolve, reject) => {
        const element = document.querySelector(selector);
        if (element) {
          resolve(element);
          return;
        }

        const observer = new MutationObserver(() => {
          const element = document.querySelector(selector);
          if (element) {
            observer.disconnect();
            resolve(element);
          }
        });

        observer.observe(document.body, {
          childList: true,
          subtree: true
        });

        setTimeout(() => {
          observer.disconnect();
          reject(new Error(`元素 ${selector} 在 ${timeout}ms 内未找到`));
        }, timeout);
      });
    },

    /**
     * 检查元素是否在视口中
     * @param {Element} element - DOM元素
     * @returns {boolean} 是否在视口中
     */
    isInViewport(element) {
      const rect = element.getBoundingClientRect();
      return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
      );
    },

    /**
     * 滚动到元素位置
     * @param {Element} element - 目标元素
     * @param {Object} options - 滚动选项
     */
    scrollToElement(element, options = {}) {
      const defaultOptions = {
        behavior: 'smooth',
        block: 'center',
        inline: 'nearest',
        ...options
      };
      element.scrollIntoView(defaultOptions);
    }
  },

  /**
   * 日志工具
   */
  logger: {
    /**
     * 调试日志
     * @param {...any} args - 日志参数
     */
    debug(...args) {
      if (this.isDebugMode()) {
        console.log('[浏览器工作流 DEBUG]', ...args);
      }
    },

    /**
     * 信息日志
     * @param {...any} args - 日志参数
     */
    info(...args) {
      console.info('[浏览器工作流 INFO]', ...args);
    },

    /**
     * 警告日志
     * @param {...any} args - 日志参数
     */
    warn(...args) {
      console.warn('[浏览器工作流 WARN]', ...args);
    },

    /**
     * 错误日志
     * @param {...any} args - 日志参数
     */
    error(...args) {
      console.error('[浏览器工作流 ERROR]', ...args);
    },

    /**
     * 检查是否为调试模式
     * @returns {boolean} 是否为调试模式
     */
    isDebugMode() {
      return localStorage.getItem('browserWorkDebugMode') === 'true';
    }
  }
};

// 如果在Node.js环境中，导出模块
if (typeof module !== 'undefined' && module.exports) {
  module.exports = BrowserWorkUtils;
}

// 如果在浏览器环境中，挂载到全局对象
if (typeof window !== 'undefined') {
  window.BrowserWorkUtils = BrowserWorkUtils;
} 